/**
 * 
 */
package com.hyfrogx.modules.app.controller.wechat;
import com.hyfrogx.common.exception.ServiceException;
import com.hyfrogx.common.param.Constants;
import com.hyfrogx.common.utils.R;
import com.hyfrogx.common.utils.Terminal;
import com.hyfrogx.config.AliPayConfig;
import com.hyfrogx.config.wx.ConfigsWx;
import com.hyfrogx.modules.app.annotation.Login;
import com.hyfrogx.modules.app.form.WePayVO;
import com.hyfrogx.modules.app.utils.*;
import com.hyfrogx.modules.charge.entity.HyCharge;
import com.hyfrogx.modules.charge.service.HyChargeService;
import com.hyfrogx.modules.manage.controller.BaseController;

import com.hyfrogx.modules.manage.entity.chargePayRecord.ChargePayRecordEntity;
import com.hyfrogx.modules.manage.service.chargePayRecord.ChargePayRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * 
 * @ClassName: ApiAliPayController
 * @Description:回调方法Controller)
 * @author Orchid
 * @date 2017年12月8日 下午2:59:42
 *
 */
@RestController
@RequestMapping(value = "api/wx")
@Api(value = "ApiAliPayController",tags = {"客户端--微信支付接口"})
public class ApiWeiXinController extends BaseController {

	Logger logger = LoggerFactory.getLogger("wxpay");
	
	@Autowired
	HyChargeService chargeService;
	
	@Autowired
	ChargePayRecordService chargePayRecordService;
	
//	@Autowired
//	HyMasterReserveService masterReserveService;

	@Autowired
	ConfigsWx configsWx;
	

	/**
	 * 微信支付获取	prepay_id
	 //* @param price	充值的价格,与支付宝的区别是支付宝单位元,微信是分;
	 * @return
	 */
	@Login
	@ApiOperation("微信支付")
	@RequestMapping(value = "sign/get", method = RequestMethod.POST)
	public R GetSign(@RequestBody WePayVO wePayVO, HttpServletRequest request) {
		try {
			String ip= CusAccessObjectUtil.getIpAddress(request);
			if (!StringUtils.ipCheck(ip)){
				throw new ServiceException("IP地址不合法");
			}
			HyCharge charge = chargeService.getById(wePayVO.getChargeId());
			if (charge == null) {
				return R.error("充值方式不存在");
			}
			if (charge.getStatus().intValue() != Constants.CommonStatus.NORMAL) {
				return R.error("该充值规则不可用");
			}
			// 交易类型
			SortedMap<String, String> packageParams = new TreeMap<String, String>();
			packageParams.put("appid", configsWx.getAppid());
			packageParams.put("body", "三眼蛙-蛙豆充值");
			packageParams.put("mch_id", configsWx.getMchid());
			packageParams.put("nonce_str", WXPayUtil.generateNonceStr());
			packageParams.put("notify_url", configsWx.getCallback_wx());
			packageParams.put("out_trade_no", WXPayUtil.generateUUID());
			packageParams.put("spbill_create_ip", ip);
			//if (IpUtils.checkIp() == false){
				//正式服，单位为分
				packageParams.put("total_fee", charge.getMoney()*100+"");
//			}else{
//				//测试服每次测试1分钱
//				packageParams.put("total_fee","1");
//			}
			packageParams.put("trade_type", "APP");
			String requestXML = WXPayUtil.generateSignedXml(packageParams, configsWx.getApi_key());
			String data = postData(configsWx.getUfdoder_url(), requestXML, "");
//			System.out.println(data);
//			System.out.println(WXPayUtil.isSignatureValid(data, WXPayUtil.getKey()));
			
			Map<String, String> map = WXPayUtil.xmlToMap(data);
			if (!map.get("return_code").equals(Constants.WeiXinStatus.SUCCESS)){
				return R.error(map.get("return_msg"));
			}else{
				if (!map.get("result_code").equals(Constants.WeiXinStatus.SUCCESS)){
					return R.error("err_code_des:"+map.get("err_code_des")+";err_code:"+map.get("err_code"));
				}else{
					
					ChargePayRecordEntity chargePayRecord = new ChargePayRecordEntity();
					chargePayRecord.setUid(wePayVO.getUid());
					chargePayRecord.setOutTradeNo(packageParams.get("out_trade_no"));
					// 测试参数,注意修改回去
					chargePayRecord.setTotalAmount(charge.getMoney());
					//应得虚拟币
					chargePayRecord.setCoin(charge.getMoney() * 10);
					//chargePayRecord.setType(wePayVO.getType());
//					int vip = userVipService.getUserVipByUid(uid);
//					if (vip != 0) {
//						if (!vipParamService.containsKey(vip)) {
//							logger.error(uid + "***" + charge.getMoney() + "***" + new Date() + "***" + "fail" + "vip:" + vip
//									+ "的不存在");
//							return ajaxFail("vip等级异常");
//						}
//						VipParam vipParam = vipParamService.findByVip(vip);
//						if (vipParam == null) {
//							logger.error(uid + "***" + charge.getMoney() + "***" + new Date() + "***" + "fail" + "vip:" + vip
//									+ "的对应参数体系是null");
//							// 丢失vip的相关规则
//							return ajaxFail("vip参数异常");
//						}
//						Integer discount = vipParam.getDiscount();
//						if (discount == null) {
//							logger.error(uid + "***" + charge.getMoney() + "***" + new Date() + "***" + "fail" + "vip:" + vip
//									+ "的对应折扣是null");
//							return ajaxFail("vip充值折扣异常");
//						}
//						// 向下取整，存入蛙豆
//						chargePayRecord.setPresentCoin((int) Math.floor(
//								(double) charge.getMoney() * AndroidChargeScale.getInstance().getScale() * discount * 0.01));
//					} else {
//						chargePayRecord.setPresentCoin(0);
//					}
					chargePayRecord.setChargePresentCoin(charge.getPresent());
/*					// 判断是不是带着邀请码注册的账号,并属于充值活动周期内
					Boolean needCoin = masterReserveService.isHaveCode(uid);
					if(needCoin){
						// 判断是否时效期内,当前测试时间为5-17日00:00:00的时间戳,十万阶梯/25%比例
						if(System.currentTimeMillis() < 1529510399000l && chargePayRecord.getCoin() <= 10000){
							chargePayRecord.setChargePresentCoin((int) Math.floor((double)chargePayRecord.getCoin() * 0.25));
						}
						// 判断是否时效期内,当前测试时间为5-17日00:00:00的时间戳,十万+阶梯/50%比例
						if(System.currentTimeMillis() < 1529510399000l && chargePayRecord.getCoin() > 10000){
							chargePayRecord.setChargePresentCoin((int) Math.floor((double)chargePayRecord.getCoin() * 0.5));
						}
					}*/
					chargePayRecord.setStatus(Constants.PayStatus.CREATE);
					chargePayRecord.setTerminal(Terminal.DisplayChannel.android);
					chargePayRecord.setChannel(Constants.PayChannel.WEIXIN);
					chargePayRecordService.save(chargePayRecord);
					SortedMap<String, String> result = new TreeMap<String, String>();
					result.put("appid", map.get("appid"));
					result.put("partnerid", configsWx.getMchid());
					result.put("prepayid", map.get("prepay_id"));
					result.put("package", "Sign=WXPay");
					result.put("noncestr", WXPayUtil.generateNonceStr());
					result.put("timestamp", DateUtils.getYYMMDDHHMMSS(new Date()));
					String val = WXPayUtil.generateSignedXml(result, configsWx.getApi_key());
					logger.info(wePayVO.getUid() + "***" + charge.getMoney() + "***" + new Date() + "***" + "success -----进入带模板id充值" + "充值规则id" + wePayVO.getChargeId() );
					return R.ok().put("map",WXPayUtil.xmlToMap(val));
				}
			}
		} catch (Exception e) {
			logger.error(wePayVO.getUid() + "***" + new Date() + "***" + "fail -----进入带模板id充值" + "充值规则id" + wePayVO.getChargeId() + e.getMessage());
			return R.error(e.getMessage());
		}
	}

	/**
	 * 微信支付获取	prepay_id
	 * @param ip	移动用户的IP
	 * @param price	充值的价格,与支付宝的区别是支付宝单位元,微信是分;
	 * @param uid	充值的用户uid
	 //* @param id	充值的订单id
	 * @param type
	 * @return
	 */
	@RequestMapping(value = "custom/sign/get", method = RequestMethod.POST)
	@ResponseBody
	public R GetCustomSign(@RequestParam(name = "spbill_create_ip", required = true) String ip,
			@RequestParam(required = true, name = "uid") Long uid,
			@RequestParam(required = true, name = "price") int price,
			@RequestParam(required = true, name = "type") int type) {
		try {
			if (!StringUtils.ipCheck(ip)){
				throw new ServiceException("IP地址不合法");
			}
			if (price < 108 || price > 100000) {
				return R.error("自定义充值最低金额为108元");
			}
			// 交易类型
			SortedMap<String, String> packageParams = new TreeMap<String, String>();
			packageParams.put("appid", configsWx.getAppid());
			packageParams.put("body", "三眼蛙-蛙豆充值");
			packageParams.put("mch_id", configsWx.getMchid());
			packageParams.put("nonce_str", WXPayUtil.generateNonceStr());
			packageParams.put("notify_url", configsWx.getCallback_wx());
			packageParams.put("out_trade_no", WXPayUtil.generateUUID());
			packageParams.put("spbill_create_ip", ip);
			/********************金额修改***************/
			if (IpUtils.checkIp() == false){
				packageParams.put("total_fee", price*100+"");
			}else{
				packageParams.put("total_fee","1");
			}
			packageParams.put("trade_type", "APP");
			String requestXML = WXPayUtil.generateSignedXml(packageParams, configsWx.getApi_key());
			String data = postData(configsWx.getUfdoder_url(), requestXML, "");
//			System.out.println(data);
//			System.out.println(WXPayUtil.isSignatureValid(data, WXPayUtil.getKey()));
			
			Map<String, String> map = WXPayUtil.xmlToMap(data);
			if (!map.get("return_code").equals(Constants.WeiXinStatus.SUCCESS)){
				return R.error(map.get("return_msg"));
			}else{
				if (!map.get("result_code").equals(Constants.WeiXinStatus.SUCCESS)){
					return R.error("err_code_des:"+map.get("err_code_des")+";err_code:"+map.get("err_code"));
				}else{
					
					ChargePayRecordEntity chargePayRecord = new ChargePayRecordEntity();
					chargePayRecord.setUid(uid);
					chargePayRecord.setOutTradeNo(packageParams.get("out_trade_no"));
					// 测试参数,注意修改回去
					chargePayRecord.setTotalAmount(price);
					chargePayRecord.setCoin(price * 10);
					//chargePayRecord.setType(type);
//					int vip = userVipService.getUserVipByUid(uid);
//					if (vip != 0) {
//						if (!vipParamService.containsKey(vip)) {
//							logger.error(uid + "***" + price + "***" + new Date() + "***" + "fail" + "vip:" + vip
//									+ "的不存在");
//							return ajaxFail("vip等级异常");
//						}
//						VipParam vipParam = vipParamService.findByVip(vip);
//						if (vipParam == null) {
//							logger.error(uid + "***" + price + "***" + new Date() + "***" + "fail" + "vip:" + vip
//									+ "的对应参数体系是null");
//							// 丢失vip的相关规则
//							return ajaxFail("vip参数异常");
//						}
//						Integer discount = vipParam.getDiscount();
//						if (discount == null) {
//							logger.error(uid + "***" + price + "***" + new Date() + "***" + "fail" + "vip:" + vip
//									+ "的对应折扣是null");
//							return ajaxFail("vip充值折扣异常");
//						}
//						// 向下取整，存入蛙豆
//						chargePayRecord.setPresentCoin((int) Math.floor(
//								(double) price * AndroidChargeScale.getInstance().getScale() * discount * 0.01));
//					} else {
//						chargePayRecord.setPresentCoin(0);
//					}
					chargePayRecord.setChargePresentCoin(0);
					// 判断是不是带着邀请码注册的账号,并属于充值活动周期内
/*					Boolean needCoin = masterReserveService.isHaveCode(uid);
					if(needCoin){
						// 判断是否时效期内,当前测试时间为5-17日00:00:00的时间戳,十万阶梯/25%比例
						if(System.currentTimeMillis() < 1529510399000l && chargePayRecord.getCoin() <= 10000){
							chargePayRecord.setChargePresentCoin((int) Math.floor((double)chargePayRecord.getCoin() * 0.25));
						}
						// 判断是否时效期内,当前测试时间为5-17日00:00:00的时间戳,十万+阶梯/50%比例
						if(System.currentTimeMillis() < 1529510399000l && chargePayRecord.getCoin() > 10000){
							chargePayRecord.setChargePresentCoin((int) Math.floor((double)chargePayRecord.getCoin() * 0.5));
						}
					}*/
					chargePayRecord.setStatus(Constants.PayStatus.CREATE);
					chargePayRecord.setTerminal(Terminal.DisplayChannel.android);
					chargePayRecord.setChannel(Constants.PayChannel.WEIXIN);
					chargePayRecordService.save(chargePayRecord);
					SortedMap<String, String> result = new TreeMap<String, String>();
					result.put("appid", map.get("appid"));
					result.put("partnerid", configsWx.getMchid());
					result.put("prepayid", map.get("prepay_id"));
					result.put("package", "Sign=WXPay");
					result.put("noncestr", WXPayUtil.generateNonceStr());
					result.put("timestamp", DateUtils.getYYMMDDHHMMSS(new Date()));
					String val = WXPayUtil.generateSignedXml(result, configsWx.getApi_key());
					logger.info(uid + "***" + price + "***" + new Date() + "***" + "success -----进入自定义充值" +  "充值金额" + price);
					return R.ok().put("map",WXPayUtil.xmlToMap(val));
					//return ajaxSuccess(WXPayUtil.xmlToMap(val));
				}
			}
		} catch (Exception e) {
			logger.error(uid + "***" + price + "***" + new Date() + "***" + "fail  -----进入自定义充值" + "充值金额" + price + e.getMessage());
			return R.error(e.getMessage());
		}
	}
	
	
	/**
	 * 发送请求的工具类
	 * @param urlStr
	 * @param data
	 * @param contentType
	 * @return
	 */
	public String postData(String urlStr, String data, String contentType) {
		BufferedReader reader = null;
		try {
			URL url = new URL(urlStr);
			URLConnection conn = url.openConnection();
			conn.setDoOutput(true);
			conn.setConnectTimeout(WXPayUtil.getHttpConnectTimeoutMs());
			conn.setReadTimeout(WXPayUtil.getHttpReadTimeoutMs());
			if (contentType != null) {
				conn.setRequestProperty("content-type", contentType);
			}
			OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), Constants.CharSet.utf8);
			if (data == null) {
				data = "";
			}
			writer.write(data);
			writer.flush();
			writer.close();
			reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), Constants.CharSet.utf8));
			StringBuilder sb = new StringBuilder();
			String line = null;
			while ((line = reader.readLine()) != null) {
				sb.append(line);
				sb.append("\r\n");
			}
			return sb.toString();
		} catch (IOException e) {
			throw new ServiceException(e.getMessage());
		} finally {
			try {
				if (reader != null) {
					reader.close();
				}
			} catch (IOException e) {
				throw new ServiceException(e.getMessage());
			}
		}
	}

	/**
	 * 取消支付
	 *
	 * @return
	 */
	@Login
	@ApiOperation("取消微信支付")
	@ResponseBody
	@RequestMapping(value = "cancle/order", method = RequestMethod.POST)
	public R cancleOrderById(@RequestParam(required = true, name = "id") Integer id,
			@RequestParam(required = true, name = "uid") Integer uid) {
		try {
			ChargePayRecordEntity payRecordEntity = new ChargePayRecordEntity();
			payRecordEntity.setStatus(ChargePayRecordConstant.PayStatus.CANCEL);
			payRecordEntity.setId(id);
			chargePayRecordService.updateById(payRecordEntity);
			logger.info(uid + "***cancle***" + id + "***" + new Date() + "***" + "success");
			return R.ok();
		} catch (Exception e) {
			logger.info(uid + "***cancle***" + id + "***" + new Date() + "***" + "fail" + e.getMessage());
			return R.error(e.getMessage());
		}
	}
	
}
